﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Collections;
using System.Data;
/*
 * This class serves the main purpose of task management
 * It is mainly used by Task.cs class to accomplish functionalities required from User Interface
 * Functionalities included:
 * Add
 * Remove
 * Clear
 * Search
 * Sort
 * Update
 * GetUpcoming
 * GetOverdue
 * GetInProgress
 * GetAll
 * GetSpecificTask
 * 
 * @Auther: Huang Purong
 * @Date: 03/09/2012
 * */

/*
 * =================================Note=========================================
 * Further refactoring and regression test maybe needed
 * ==============================================================================
 * */
namespace E.Y.E.Jobs
{    
    class TaskManager
    {
        private string _filePath;

        //Get File Path
        public TaskManager(string fileName)
        {
            _filePath = Application.StartupPath + "\\" + fileName;
        }

        /*
         * Private Methods - For internal Operation
         * */
        private ArrayList RetrieveItemsFromFile()
        {
            StreamReader srReadFile = new StreamReader(_filePath);
            string strCurrentLine = string.Empty;
            Task taskFromFile = new Task();
            ArrayList listFromFile = new ArrayList();
            int itemCount = 0;
            string[] strTask = new string[9];
            try
            {
                while ((strCurrentLine = srReadFile.ReadLine()) != null)
                {
                    if (strCurrentLine.ToLower() != "<task>" && strCurrentLine != "<\task>")
                    {
                        strTask[itemCount] = strCurrentLine;
                        itemCount++;
                        if (itemCount == 9)
                        {
                            AssignTask(ref taskFromFile, ref strTask,ref listFromFile);
                            itemCount = 0;
                        }
                    }
                }
                srReadFile.Close();
            }
            catch (Exception ex)
            {
            }
            return listFromFile;
        }
        private void AssignTask(ref Task currentTask, ref string[] currentTaskString, ref ArrayList currentListFromFile)
        {
            try
            {
                if (!string.IsNullOrEmpty(currentTaskString[0]) && !string.IsNullOrWhiteSpace(currentTaskString[0]))
                {
                    currentTask.ID = Convert.ToInt16(currentTaskString[0]);
                }
                currentTask.Detail = currentTaskString[1];
                currentTask.Venue = currentTaskString[2];
                if (!string.IsNullOrEmpty(currentTaskString[3]) && !string.IsNullOrWhiteSpace(currentTaskString[3]))
                {
                    currentTask.StartTime = Convert.ToDateTime(currentTaskString[3]);
                }
                if (!string.IsNullOrEmpty(currentTaskString[4]) && !string.IsNullOrWhiteSpace(currentTaskString[4]))
                {
                    currentTask.EndTime = Convert.ToDateTime(currentTaskString[4]);
                }
                if (!string.IsNullOrEmpty(currentTaskString[5]) && !string.IsNullOrWhiteSpace(currentTaskString[5]))
                {
                    currentTask.Status = (TaskEnumTypes.TaskStatus)Enum.Parse(typeof(TaskEnumTypes.TaskStatus), currentTaskString[5], true);
                }
                if (!string.IsNullOrEmpty(currentTaskString[6]) && !string.IsNullOrWhiteSpace(currentTaskString[6]))
                {
                    currentTask.Priority = (TaskEnumTypes.TaskPriority)Enum.Parse(typeof(TaskEnumTypes.TaskPriority), currentTaskString[6], true);
                }
                if (!string.IsNullOrEmpty(currentTaskString[7]) && !string.IsNullOrWhiteSpace(currentTaskString[7]))
                {
                    currentTask.TypeOfReminder = (TaskEnumTypes.ReminderType)Enum.Parse(typeof(TaskEnumTypes.ReminderType), currentTaskString[7], true);
                }
                if (!string.IsNullOrEmpty(currentTaskString[8]) && !string.IsNullOrWhiteSpace(currentTaskString[8]))
                {
                    currentTask.RemindBefore = TimeSpan.Parse(currentTaskString[8]);
                }
                    
            }
            catch (Exception ex)
            {
            }
        }
        private void WriteBackToFile(ArrayList updatedTaskList)
        {
            try
            {
                File.WriteAllText(_filePath, string.Empty);
                StreamWriter swWriteToFile = new StreamWriter(_filePath);
                string strLine = string.Empty;

                foreach (object objItem in updatedTaskList)
                {
                    Task tskItem = (Task)objItem;
                    swWriteToFile.WriteLine("<task>");
                    WriteTaskToFile(ref swWriteToFile, ref tskItem);
                    swWriteToFile.WriteLine("<\task>");
                }
                swWriteToFile.Close();
            }
            catch (Exception ex)
            {
            }
        }
        private void WriteTaskToFile(ref StreamWriter swWriteToFile, ref Task tskItem)
        {
            try
            {
                swWriteToFile.WriteLine(tskItem.ID.ToString());
                swWriteToFile.WriteLine(tskItem.Detail);
                swWriteToFile.WriteLine(tskItem.Venue);
                if (tskItem.StartTime == null)
                {
                    swWriteToFile.WriteLine(" ");
                }
                else
                {
                    swWriteToFile.WriteLine(tskItem.StartTime.ToString());
                }
                if (tskItem.EndTime == null)
                {
                    swWriteToFile.WriteLine(" ");
                }
                else
                {
                    swWriteToFile.WriteLine(tskItem.EndTime.ToString());
                }
                if (tskItem.Status == null)
                {
                    swWriteToFile.WriteLine(" ");
                }
                else
                {
                    swWriteToFile.WriteLine(tskItem.Status.ToString());
                }
                if (tskItem.Priority == null)
                {
                    swWriteToFile.WriteLine(" ");
                }
                else
                {
                    swWriteToFile.WriteLine(tskItem.Priority.ToString());
                }
                if (tskItem.TypeOfReminder == null)
                {
                    swWriteToFile.WriteLine(" ");
                }
                else
                {
                    swWriteToFile.WriteLine(tskItem.TypeOfReminder.ToString());
                }
                if (tskItem.RemindBefore == null)
                {
                    swWriteToFile.WriteLine(" ");
                }
                else
                {
                    swWriteToFile.WriteLine(tskItem.RemindBefore.ToString());
                }
            }
            catch (Exception ex)
            {
            }
        }
        private ArrayList IndexList(ArrayList originalList)
        {
            int index = 0;

            foreach (Task tskItem in originalList)
            {
                tskItem.ID = ++index;
            }
            return originalList;
        }
        private void UpdateAccordingItems(ref Task originalTask, ref Task updatedTask)
        {
            try
            {
                originalTask.ID = updatedTask.ID;
                originalTask.Detail = updatedTask.Detail;
                originalTask.Venue = updatedTask.Venue;
                originalTask.StartTime = updatedTask.StartTime;
                originalTask.EndTime = updatedTask.EndTime;
                originalTask.Status = updatedTask.Status;
                originalTask.Priority = updatedTask.Priority;
                originalTask.TypeOfReminder = updatedTask.TypeOfReminder;
                originalTask.RemindBefore = updatedTask.RemindBefore;
            }
            catch (Exception ex)
            {
            }
        }

        /*
         * Main functions available to user
         * */
        public Boolean Remove(int index)
        {
            ArrayList listFromFile = RetrieveItemsFromFile();

            if (listFromFile.Count == 0 || index > listFromFile.Count)
            {
                return false;
            }
            else
            {
                try
                {
                    listFromFile.RemoveAt(index - 1);
                    ArrayList indexedList = IndexList(listFromFile);
                    File.WriteAllText(_filePath, string.Empty);
                    WriteBackToFile(indexedList);
                }
                catch (Exception ex)
                {
                }
                return true;
            }
        }
        public void Add(ref Task newTask)
        {
            try
            {
                ArrayList listFromFile = RetrieveItemsFromFile();
                listFromFile.Add(newTask);
                ArrayList indexedList = IndexList(listFromFile);
                WriteBackToFile(indexedList);
            }
            catch (Exception ex)
            {
            }
        }
        public void Clear()
        {
            try
            {
                File.WriteAllText(_filePath, string.Empty);
            }
            catch (Exception ex)
            {
            }
        }
        public ArrayList Search(string itemToSearch)
        {
            ArrayList ResultOfSearch = new ArrayList();
            ArrayList listFromFile = RetrieveItemsFromFile();
            string[] strKeyWords = itemToSearch.ToLower().Split(' ');
            try
            {
                foreach(object objItem in listFromFile)
                {   
                    Task tskItem = (Task)objItem;
                    switch(strKeyWords[0])
                    {
                        case "id:":
                            if(tskItem.ID.ToString() == strKeyWords[1])
                            {
                                ResultOfSearch.Add(tskItem);
                            }
                            break;
                        case "detail:":
                            if(tskItem.Detail == strKeyWords[1])
                            {
                                ResultOfSearch.Add(tskItem);
                            }
                            break;
                        case "venue:":
                            if(tskItem.Venue == strKeyWords[1])
                            {
                                ResultOfSearch.Add(tskItem);
                            }
                            break;
                        case "starttime:":
                            if(tskItem.StartTime.ToString() == strKeyWords[1])
                            {
                                ResultOfSearch.Add(tskItem);
                            }
                            break;
                        case "endtime:":
                            if(tskItem.EndTime.ToString() == strKeyWords[1])
                            {
                                ResultOfSearch.Add(tskItem);
                            }
                            break;
                        case "status:":
                           if(tskItem.Status.ToString() == strKeyWords[1])
                            {
                                ResultOfSearch.Add(tskItem);
                            }
                            break;
                        case "priority:":
                            if(tskItem.Priority.ToString() == strKeyWords[1])
                            {
                                ResultOfSearch.Add(tskItem);
                            }
                            break;
                        case "typeofreminder:":
                           if(tskItem.TypeOfReminder.ToString() == strKeyWords[1])
                            {
                                ResultOfSearch.Add(tskItem);
                            }
                            break;
                        case "remindbefore:":
                            if(tskItem.RemindBefore.ToString() == strKeyWords[1])
                            {
                                ResultOfSearch.Add(tskItem);
                            }
                            break;
                        default:
                            break;
                    }
                }
            }
            catch(Exception ex)
            {
            }
            return ResultOfSearch;
        }
        public void Update(Task newUpdateTask)
        {
            ArrayList listFromFile = RetrieveItemsFromFile();

            try
            {
                foreach (object objItem in listFromFile)
                {
                    Task originalItem = (Task)objItem;
                    if (originalItem.ID == newUpdateTask.ID)
                    {
                        UpdateAccordingItems(ref originalItem, ref newUpdateTask);
                    }
                    break;
                }
            }
            catch (Exception ex)
            {
            }
        }
        public void Sort()
        {
            try
            {
                ArrayList listFromFile = RetrieveItemsFromFile();
                listFromFile.Sort();
                ArrayList indexedList = IndexList(listFromFile);
                WriteBackToFile(indexedList);
            }
            catch (Exception ex)
            {
            }
        }
        public ArrayList GetUpcoming()
        {
            ArrayList listFromFile = RetrieveItemsFromFile();
            ArrayList upcomingList = new ArrayList();
            try
            {
                foreach (object objItem in listFromFile)
                {
                    Task tskItem = (Task)objItem;
                    if (tskItem.StartTime < DateTime.Now)
                    {
                        upcomingList.Add(tskItem);
                    }
                }
            }
            catch (Exception ex)
            {
            }
            return upcomingList;
        }
        public ArrayList GetOverall()
        {
            ArrayList listFromFile = new ArrayList();
            try
            {
                listFromFile = RetrieveItemsFromFile();
            }
            catch (Exception ex)
            {
            }
            return listFromFile;
        }
        public ArrayList GetOverdue()
        {
            ArrayList listFromFile = RetrieveItemsFromFile();
            ArrayList overdueList = new ArrayList();
            try
            {
                foreach (object objItem in listFromFile)
                {
                    Task tskItem = (Task)objItem;
                    if (tskItem.StartTime < DateTime.Now && tskItem.EndTime < DateTime.Now)
                    {
                        overdueList.Add(tskItem);
                    }
                }
            }
            catch (Exception ex)
            {
            }
            return overdueList;
        }
        public ArrayList GetInProgress()
        {
            ArrayList listFromFile = RetrieveItemsFromFile();
            ArrayList inProgressList = new ArrayList();
            try
            {
                foreach (object objItem in listFromFile)
                {
                    Task tskItem = (Task)objItem;
                    if (tskItem.StartTime < DateTime.Now && tskItem.EndTime > DateTime.Now)
                    {
                        inProgressList.Add(tskItem);
                    }
                }
            }
            catch (Exception ex)
            {
            }
            return inProgressList;
        }
        public Task GetSpecificTask(int taskIndex)
        {
            Task matchedTask = new Task();
            try
            {
                ArrayList listFromFile = RetrieveItemsFromFile();
                for (int i = 0; i <= listFromFile.Count; i++)
                {
                    Task tskItem = (Task)listFromFile[i];
                    if (taskIndex == tskItem.ID)
                    {
                        matchedTask.ID = tskItem.ID;
                        matchedTask.Detail = tskItem.Detail;
                        matchedTask.Venue = tskItem.Venue;
                        matchedTask.StartTime = tskItem.StartTime;
                        matchedTask.EndTime = tskItem.EndTime;
                        matchedTask.Status = tskItem.Status;
                        matchedTask.Priority = tskItem.Priority;
                        matchedTask.TypeOfReminder = tskItem.TypeOfReminder;
                        matchedTask.RemindBefore = tskItem.RemindBefore;
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
            }
            return matchedTask;
        }

        public ArrayList GetCurrentList()
        {
            return new ArrayList();
        }

        public bool RestoreList(ArrayList OriginalDatabase)
        {
            return false;
        }

        public ArrayList Search(ArrayList SearchCriteria)
        {
            return new ArrayList();
        }
    }
}
